package com.study.util;

import java.lang.reflect.Field;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 数据校验工具
 *
 * @author whl
 */
public class DataVerificationUtil {
    /**
     * 判断对象是否为null
     *
     * @param objs 对象
     * @return true 非null false 为null
     */
    public static boolean isNull(Object... objs) {
        for (Object obj : objs) {
            if (null != obj) {
                if (obj instanceof String) {
                    String s = String.valueOf(obj);
                    if ("".equals(s.trim()) || "null".equals(s.trim())) {
                        return false;
                    }
                } else if (obj instanceof Map) {
                    Map map = (Map) obj;
                    if (map.isEmpty()) {
                        return false;
                    }
                }
            } else {
                return false;
            }
        }
        return true;
    }

    /**
     * 通过反射校验对象中的属性
     *
     * @param obj            被校验的对象
     * @param type           校验方式：type为true propertieNames中的属性名为需要校验的; type为false
     *                       propertieNames中的属性名为不需要校验的
     * @param propertieNames 属性名数组
     * @return 未通过校验的属性名数组
     */
    public static List<String> checkObjectPropertiesNotNull(Object obj, boolean type, String... propertieNames) {
        List<String> fileNames = new ArrayList();
        if (obj == null) {
            fileNames.add("obj");
            return fileNames;
        }
        String[] names;
        if (propertieNames != null) {
            names = new String[propertieNames.length];
            for (int i = 0; i < propertieNames.length; i++) {
                names[i] = propertieNames[i].toLowerCase(Locale.ENGLISH);
            }
        } else {
            names = new String[0];
        }
        try {
            Field[] fields = obj.getClass().getDeclaredFields();
            for (int i = 0; i < fields.length; i++) {
                Field field = fields[i];
                field.setAccessible(true);
                String fieldName = field.getName().toLowerCase(Locale.ENGLISH);
                if (type) {
                    if (isArray(names, fieldName) && !isNull(field.get(obj))) {
                        fileNames.add(fieldName);
                    }
                } else {
                    if (!isArray(names, fieldName) && !isNull(field.get(obj))) {
                        fileNames.add(fieldName);
                    }
                }
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        System.out.println("null fileNames:" + fileNames);
        return fileNames;
    }

    /**
     * 判断是否存在于数组中
     *
     * @param array 数组
     * @param param 要判断的元素
     * @return true 存在   false 不存在
     */
    public static boolean isArray(String array[], String param) {
        for (String str : array) {
            if (str.equals(param)) {
                return true;
            }
        }
        return false;
    }

    private static Pattern EMAIL_PATTERN = Pattern.compile("^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$");

    /**
     * 判断字符串是否符合邮箱地址
     *
     * @param param 被校验的数据
     * @return true 符合 false 不符合
     */
    public static boolean isEmail(String param) {
        if (isNull(param)) {
            Matcher matcher = EMAIL_PATTERN.matcher(param);
            return matcher.find();
        }
        return false;
    }

    private static Pattern MOBILE_PATTERN = Pattern.compile("^((13[0-9])|(15[^4,\\D])|(18[0,5-9]))\\d{8}$");

    /**
     * 判断字符串是否符合手机号码
     *
     * @param param 被校验的数据
     * @return true 符合 false 不符合
     */
    public static boolean isMobile(String param) {
        if (isNull(param)) {
            Matcher matcher = MOBILE_PATTERN.matcher(param);
            return matcher.find();
        }
        return false;
    }

    /**
     * 对map进行校验
     *
     * @param map            需要校验的map
     * @param type           校验方式：type为true propertieNames中的属性名为需要校验的; type为false
     *                       propertieNames中的属性名为不需要校验的
     * @param propertieNames 属性名数组
     * @return 未通过校验的属性名数组
     */
    public static List<String> checkMap(Map<String, Object> map, boolean type, String... propertieNames) {
        List<String> fileNames = new ArrayList();
        Set<String> keys = map.keySet();
        for (String propertieName : propertieNames) {
            //如果map的key集合中不包含  要检查的属性
            if (type) {
                if (!keys.contains(propertieName)) {
                    fileNames.add(propertieName);
                }
            } else {
                if (keys.contains(propertieName)) {
                    keys.remove(propertieName);
                }
            }
        }
        for (String key : keys) {
            if (!isNull(map.get(key))) {
                fileNames.add(key);
            }
        }
        return fileNames;
    }

}
